package com.zhl.utils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

import java.sql.SQLException;

/**
 * 事务管理
 */
@Component //创建bean对象
@Aspect // 配置切面
@EnableAspectJAutoProxy //启用Aop的切面(将代理的方法应用到通知类中)
public class TransactionManager {
    //定义切点表达式
    @Pointcut("execution(* com.zhl.service.impl.*.*(..))")
    public void pt(){}


    @Autowired
    private ConnUtils connUtils;
    //开启事务
    public void beginTransaction(){
        try {
            connUtils.getConnection().setAutoCommit(false);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    //提交事务
    public void commit(){
        try {
            connUtils.getConnection().commit();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    //事务回滚
    public void rollback(){
        try {
            connUtils.getConnection().rollback();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    //释放连接
    public void close(){
        try {
            //释放数据库连接对象conn
            connUtils.getConnection().close();
            //解绑线程
            connUtils.remove();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }


    //环绕通知
    @Around("pt()")
    public Object aroundType(ProceedingJoinPoint pjp){
        Object obj = null;
        try {
            Object[] args = pjp.getArgs();
            //前置通知
            this.beginTransaction();
            //业务
            obj = pjp.proceed(args);
            //后置通知
            this.commit();
            return obj;
        } catch (Throwable e) {
            //异常通知
            this.rollback();
           throw new RuntimeException(e);
        }finally {
            //最终通知
            this.close();
        }


    }

}
